home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / jwpsrc.zip / MISC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-31  |  42.0 KB  |  1,286 lines

  1. /* Copyright (C) Stephen Chung, 1991-1993.  All rights reserved. */
  2.  
  3. #include "jwp.h"
  4.  
  5. #include "idm.h"
  6.  
  7. #include <dir.h>
  8. #include <sys/stat.h>
  9.  
  10. static long int percent, ohpercent;
  11. static int HeaderNum;
  12. static BOOL LeftRight;
  13.  
  14. static char *filespec = NULL;
  15. static KANJI far *criteria[NRSUMMARIES] = { NULL, NULL, NULL, NULL, NULL };
  16. static char *FileInfoName;
  17.  
  18. extern BOOL Dialogs3D;
  19.  
  20. #define PARENTDIR   "<Go Up>"
  21. #define DRIVECHAR   '['
  22. #define FILENAMELEN 15
  23. #define NRQUICKFILE 4
  24.  
  25. #define NRPROGS     4
  26.  
  27.  
  28. static char *QuickFiles[NRQUICKFILE];
  29.  
  30. #define TPLBLOCKSIZE    5
  31.  
  32. typedef struct {
  33.     char far *filename;
  34.     KANJI far *desc;
  35. } TPLFILE;
  36.  
  37. char far *TplChosen = NULL;
  38. static TPLFILE far *Templates = NULL;
  39. static int nr_templates = 0;
  40.  
  41.  
  42.  
  43. BOOL FAR PASCAL StatisticsProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  44. {
  45.     long int allocated, requests, hits, usage, overhead;
  46.     long int len;
  47.     int      num;
  48.     HWND     barhwnd;
  49.     RECT     rect;
  50.     HDC      hdc;
  51.     char     buffer[BUFSIZE];
  52.  
  53.     switch (message) {
  54.  
  55.         case WM_INITDIALOG:
  56.             FontCacheStatistics (&num, &usage, &requests, &hits);
  57.             sprintf(buffer, "%d Font Cache%s:", num, (num > 1) ? "s" : "");
  58.             SetDlgItemText(hwnd, 4201, buffer);
  59.             if (requests > 0L) {
  60.                 sprintf(buffer, "%ld / %ld  (%d%%)  %ld cached",
  61.                             hits, requests, (int) (100.0 * ((double) hits) / ((double) requests)), usage);
  62.             } else {
  63.                 sprintf(buffer, "%ld cached", usage);
  64.             }
  65.             SetDlgItemText(hwnd, 4202, buffer);
  66.  
  67.             ConvCacheStatistics (&usage, &requests, &hits);
  68.             if (requests > 0L) {
  69.                 sprintf(buffer, "%ld / %ld  (%d%%)  %ld cached",
  70.                             hits, requests, (int) (100.0 * ((double) hits) / ((double) requests)), usage);
  71.             } else {
  72.                 sprintf(buffer, "%ld cached", usage);
  73.             }
  74.             SetDlgItemText(hwnd, 4212, buffer);
  75.  
  76.             if (global.active != NULL) {
  77.                 sprintf(buffer, "%ld character%s", global.active->nr_bytes,
  78.                             (global.active->nr_bytes > 1L) ? "s" : "");
  79.                 SetDlgItemText(hwnd, 4221, buffer);
  80.  
  81.                 if (global.active->undolevels > 0) {
  82.                     sprintf(buffer, "%d change%s retained", global.active->undolevels,
  83.                             (global.active->undolevels > 1) ? "s" : "");
  84.                 } else {
  85.                     strcpy(buffer, "No changes retained");
  86.                 }
  87.                 SetDlgItemText(hwnd, 4222, buffer);
  88.             } else {
  89.                 SetDlgItemText(hwnd, 4221, "No active file");
  90.             }
  91.  
  92.             CountMemoryUsage(&allocated, &usage, &overhead);
  93.  
  94.             sprintf(buffer,"Memory Usage Efficiency (%ldK Allocated):", (allocated / 1024L) + 1);
  95.             SetDlgItemText(hwnd, 4231, buffer);
  96.  
  97.             percent = (((usage + overhead) * 100L) / allocated) + 1L;
  98.             if (percent > 100L) percent = 100L;
  99.  
  100.             ohpercent = ((usage * 100L) / allocated) + 1L;
  101.             if (ohpercent > 100L) ohpercent = 100L;
  102.  
  103.             sprintf(buffer,"%ld%%", percent);
  104.             SetDlgItemText(hwnd, 4233, buffer);
  105.  
  106.             CenterDialogBox(hwnd);
  107.  
  108.             return (TRUE);
  109.  
  110.         case WM_PAINT:
  111.             barhwnd = GetDlgItem(hwnd, 4232);
  112.             GetClientRect(barhwnd, &rect);
  113.  
  114.             len = (rect.right - 4) * percent / 100L;
  115.  
  116.             hdc = GetDC(barhwnd);
  117.             SelectObject(hdc, GetStockObject(GRAY_BRUSH));
  118.             Rectangle(hdc, 2, 2, len + 2, rect.bottom - 2);
  119.  
  120.             len = (rect.right - 4) * ohpercent / 100L;
  121.             if (Dialogs3D) {
  122.                 SelectObject(hdc, GetStockObject(BLACK_BRUSH));
  123.             } else {
  124.                 SelectObject(hdc, GetStockObject(LTGRAY_BRUSH));
  125.             }
  126.             Rectangle(hdc, 2, 2, len + 2, rect.bottom - 2);
  127.             ReleaseDC(barhwnd, hdc);
  128.             break;
  129.  
  130.         case WM_KEYDOWN:
  131.             switch (wParam) {
  132.                 case VK_ESCAPE: SendMessage(hwnd, WM_COMMAND, IDOK, 0L);
  133.                                 return (TRUE);
  134.             }
  135.             break;
  136.  
  137.         case WM_COMMAND:
  138.             switch (wParam) {
  139.                 case IDOK:
  140.                 case IDCANCEL:  EndDialog(hwnd, 0); return (TRUE);
  141.             }
  142.             break;
  143.     }
  144.  
  145.     return (FALSE);
  146. }
  147.  
  148.  
  149.  
  150. BOOL FAR PASCAL SummaryProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  151. {
  152.     switch (message) {
  153.         case WM_INITDIALOG: {
  154.             int i, len;
  155.             FILEOPTIONS *f, *f1;
  156.             KANJI buffer[MAXLINELEN];
  157.  
  158.             /* Set the type and mode-change icon of the Jedit controls */
  159.  
  160.             f1 = global.active;
  161.  
  162.             for (i = 0; i < NRSUMMARIES; i++) {
  163.                 SendDlgItemMessage(hwnd, 4201 + i, EM_SETRECT, GetDlgItem(hwnd, 4211), 0L);
  164.                 f = (FILEOPTIONS *) SendDlgItemMessage(hwnd, 4201 + i, EM_GETHANDLE, 0, 0L);
  165.  
  166.                 if (f1 != NULL && f1->summary[i] != NULL) {
  167.                     kanjicpy(buffer, f1->summary[i]);
  168.                     SendDlgItemMessage(hwnd, 4201 + i, EM_REPLACESEL, 0, (LONG) buffer);
  169.                 } else {
  170.                     buffer[0] = 0;
  171.                 }
  172.                 if (i == 0) {
  173.                     len = kanjilen(buffer);
  174.                     SendDlgItemMessage(hwnd, 4211, EM_SETHANDLE, f->hwnd, 0L);  /* icon-change */
  175.                 }
  176.             }
  177.  
  178.             if (len > 0) SendDlgItemMessage(hwnd, 4201, EM_SETSEL, len, MAKELONG(0, len - 1));
  179.             SetFocus(GetDlgItem(hwnd, 4201));
  180.             CenterDialogBox(hwnd);
  181.             return (TRUE);
  182.         }
  183.  
  184.         case WM_PAINT: {
  185.             int i;
  186.             HDC hdc;
  187.             PAINTSTRUCT ps;
  188.  
  189.             hdc = BeginPaint(hwnd, &ps);
  190.  
  191.             for (i = 0; i < NRSUMMARIES; i++) DrawBoundingBox(hwnd, hdc, 4201 + i);
  192.  
  193.             EndPaint(hwnd, &ps);
  194.             return (TRUE);
  195.         }
  196.  
  197.         case WM_COMMAND: {
  198.             int i, j, len;
  199.             KANJI far *kp;
  200.             UNIT far *up;
  201.  
  202.             switch (wParam) {
  203.                 case IDOK:
  204.                     if (global.active != NULL) {
  205.                         for (i = 0; i < NRSUMMARIES; i++) {
  206.                             up = (UNIT far *) SendDlgItemMessage(hwnd, 4201 + i, EM_GETLINE, 0, 0L);
  207.                             len = unitlen(up);
  208.  
  209.                             if (len <= 0) {
  210.                                 if (global.active->summary[i] != NULL) {
  211.                                     FreeBlock(global.active->summary[i]);
  212.                                     global.active->summary[i] = NULL;
  213.                                 }
  214.                             } else {
  215.                                 kp = global.active->summary[i];
  216.                                 if (kp == NULL) {
  217.                                     kp = (KANJI far *) BlockAlloc((len + 5) * sizeof(KANJI));
  218.                                 } else if ((SegHeapGetSize(kp) / sizeof(KANJI)) < len + 5) {
  219.                                     FreeBlock(kp);
  220.                                     kp = (KANJI far *) BlockAlloc((len + 5) * sizeof(KANJI));
  221.                                 }
  222.                                 for (j = 0; up[j].kanji; j++) kp[j] = up[j].kanji;
  223.                                 kp[j] = 0;
  224.                                 global.active->summary[i] = kp;
  225.                             }
  226.                         }
  227.                     }
  228.                     EndDialog(hwnd, TRUE);
  229.                     return (TRUE);
  230.  
  231.                 case IDCANCEL:
  232.                     EndDialog(hwnd, FALSE);
  233.                     return (TRUE);
  234.             }
  235.             break;
  236.         }
  237.     }
  238.     return (FALSE);
  239. }
  240.  
  241.  
  242.  
  243. BOOL FAR PASCAL EditHeaderProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  244. {
  245.     switch (message) {
  246.         case WM_INITDIALOG: {
  247.             int i, len;
  248.             FILEOPTIONS *f;
  249.             KANJI far *kp;
  250.  
  251.             if (LeftRight) {
  252.                 switch (HeaderNum) {
  253.                     case 0: SetWindowText(hwnd, "Edit Left Page Header"); break;
  254.                     case 1: SetWindowText(hwnd, "Edit Right Page Header"); break;
  255.                     case 2: SetWindowText(hwnd, "Edit Left Page Footer"); break;
  256.                     case 3: SetWindowText(hwnd, "Edit Right Page Footer"); break;
  257.                 }
  258.             } else {
  259.                 switch (HeaderNum) {
  260.                     case 1:
  261.                     case 0: SetWindowText(hwnd, "Edit Header"); break;
  262.                     case 3:
  263.                     case 2: SetWindowText(hwnd, "Edit Footer"); break;
  264.                 }
  265.             }
  266.  
  267.             /* Set the type and mode-change icon */
  268.             for (i = 0; i < NRHEADERS; i++) {
  269.                 SendDlgItemMessage(hwnd, 4201 + i, EM_SETRECT, GetDlgItem(hwnd, 4211), 0L);
  270.                 kp = global.active->header[HeaderNum][i];
  271.                 if (kp != NULL) {
  272.                     SendDlgItemMessage(hwnd, 4201 + i, EM_REPLACESEL, 0, (LONG) kp);
  273.                     len = kanjilen(kp);
  274.                     if (i == 0 && len > 0) {
  275.                         SendDlgItemMessage(hwnd, 4201, EM_SETSEL, len, MAKELONG(0, len - 1));
  276.                     }
  277.                 }
  278.             }
  279.  
  280.             f = (FILEOPTIONS *) SendDlgItemMessage(hwnd, 4201, EM_GETHANDLE, 0, 0L);
  281.             SendDlgItemMessage(hwnd, 4211, EM_SETHANDLE, f->hwnd, 0L);  /* Mode-change icon */
  282.             SetFocus(GetDlgItem(hwnd, 4201));
  283.  
  284.             CenterDialogBox(hwnd);
  285.             return (TRUE);
  286.         }
  287.  
  288.         case WM_PAINT: {
  289.             int i;
  290.             HDC hdc;
  291.             PAINTSTRUCT ps;
  292.  
  293.             hdc = BeginPaint(hwnd, &ps);
  294.  
  295.             for (i = 0; i < NRHEADERS; i++) DrawBoundingBox(hwnd, hdc, 4201 + i);
  296.  
  297.             EndPaint(hwnd, &ps);
  298.             return (TRUE);
  299.         }
  300.  
  301.         case WM_COMMAND:
  302.             switch (wParam) {
  303.                 case IDOK: {
  304.                     int i, j, len;
  305.                     UNIT far *up;
  306.                     KANJI far *kp;
  307.  
  308.                     for (i = 0; i < NRHEADERS; i++) {
  309.                         up = (UNIT far *) SendDlgItemMessage(hwnd, 4201 + i, EM_GETLINE, 0, 0L);
  310.                         len = unitlen(up);
  311.  
  312.                         if (len <= 0) {
  313.                             if (global.active->header[HeaderNum][i] != NULL) {
  314.                                 FreeBlock(global.active->header[HeaderNum][i]);
  315.                                 global.active->header[HeaderNum][i] = NULL;
  316.                             }
  317.                         } else {
  318.                             kp = global.active->header[HeaderNum][i];
  319.                             if (kp == NULL) {
  320.                                 kp = (KANJI far *) BlockAlloc((len + 5) * sizeof(KANJI));
  321.                             } else if ((SegHeapGetSize(kp) / sizeof(KANJI)) < len + 5) {
  322.                                 FreeBlock(kp);
  323.                                 kp = (KANJI far *) BlockAlloc((len + 5) * sizeof(KANJI));
  324.                             }
  325.                             for (j = 0; up[j].kanji; j++) kp[j] = up[j].kanji;
  326.                             kp[j] = 0;
  327.                             global.active->header[HeaderNum][i] = kp;
  328.                         }
  329.                     }
  330.  
  331.                     EndDialog(hwnd, TRUE);
  332.                     return (TRUE);
  333.                 }
  334.  
  335.                 case IDCANCEL:
  336.                     EndDialog(hwnd, FALSE);
  337.                     return (TRUE);
  338.             }
  339.             break;
  340.     }
  341.     return (FALSE);
  342. }
  343.  
  344.  
  345.  
  346. BOOL FAR PASCAL HeaderProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  347. {
  348.     switch (message) {
  349.         case WM_INITDIALOG: {
  350.             if (global.active->lrheader) {
  351.                 LeftRight = TRUE;
  352.  
  353.                 SendDlgItemMessage(hwnd, 4211, LB_ADDSTRING, 0, (LONG) "Left Header");
  354.                 SendDlgItemMessage(hwnd, 4211, LB_ADDSTRING, 0, (LONG) "Right Header");
  355.                 SendDlgItemMessage(hwnd, 4211, LB_ADDSTRING, 0, (LONG) "Left Footer");
  356.                 SendDlgItemMessage(hwnd, 4211, LB_ADDSTRING, 0, (LONG) "Right Footer");
  357.             } else {
  358.                 LeftRight = FALSE;
  359.  
  360.                 SendDlgItemMessage(hwnd, 4211, LB_ADDSTRING, 0, (LONG) "Header");
  361.                 SendDlgItemMessage(hwnd, 4211, LB_ADDSTRING, 0, (LONG) "Footer");
  362.             }
  363.  
  364.             SendDlgItemMessage(hwnd, 4211, LB_SETCURSEL, 0, 0L);
  365.  
  366.             CheckDlgButton(hwnd, 4221, global.active->lrheader);
  367.             CheckDlgButton(hwnd, 4222, global.active->nofirstpage);
  368.  
  369.             CenterDialogBox(hwnd);
  370.             return (TRUE);
  371.         }
  372.  
  373.         case WM_COMMAND:
  374.             switch (wParam) {
  375.                 case 4211:
  376.                     if (HIWORD(lParam) == LBN_DBLCLK) {
  377.                         SendMessage(hwnd, WM_COMMAND, 4201, MAKELONG(GetDlgItem(hwnd, 4201), BN_CLICKED));     /* Edit button */
  378.                     }
  379.                     return (TRUE);
  380.  
  381.                 case 4221:      /* Left/Right headers */
  382.                     if (LeftRight != IsDlgButtonChecked(hwnd, 4221)) {
  383.                         LeftRight = IsDlgButtonChecked(hwnd, 4221);
  384.  
  385.                         SendDlgItemMessage(hwnd, 4211, WM_SETREDRAW, FALSE, 0L);
  386.                         SendDlgItemMessage(hwnd, 4211, LB_RESETCONTENT, 0, 0L);
  387.                         if (LeftRight) {
  388.                             SendDlgItemMessage(hwnd, 4211, LB_ADDSTRING, 0, (LONG) "Left Header");
  389.                             SendDlgItemMessage(hwnd, 4211, LB_ADDSTRING, 0, (LONG) "Right Header");
  390.                             SendDlgItemMessage(hwnd, 4211, LB_ADDSTRING, 0, (LONG) "Left Footer");
  391.                             SendDlgItemMessage(hwnd, 4211, LB_ADDSTRING, 0, (LONG) "Right Footer");
  392.                         } else {
  393.                             SendDlgItemMessage(hwnd, 4211, LB_ADDSTRING, 0, (LONG) "Header");
  394.                             SendDlgItemMessage(hwnd, 4211, LB_ADDSTRING, 0, (LONG) "Footer");
  395.                         }
  396.                         SendDlgItemMessage(hwnd, 4211, LB_SETCURSEL, 0, 0L);
  397.                         SendDlgItemMessage(hwnd, 4211, WM_SETREDRAW, TRUE, 0L);
  398.                         InvalidateRect(hwnd, NULL, TRUE);
  399.                     }
  400.                     return (TRUE);
  401.  
  402.                 case 4201: {    /* Edit */
  403.                     int i;
  404.  
  405.                     i = SendDlgItemMessage(hwnd, 4211, LB_GETCURSEL, 0, 0L);
  406.                     if (i == LB_ERR) {
  407.                         MessageBeep(0);
  408.                         return (TRUE);
  409.                     }
  410.  
  411.                     if (LeftRight) {
  412.                         HeaderNum = i;
  413.                     } else {
  414.                         HeaderNum = i * 2;
  415.                     }
  416.  
  417.                     i = DialogBox (hInstance, "EditHeader", hwnd, EditHeaderProc);
  418.  
  419.                     if (i) ShowWindow(GetDlgItem(hwnd, IDCANCEL), SW_HIDE);
  420.  
  421.                     return (TRUE);
  422.                 }
  423.  
  424.                 case IDOK:
  425.                     global.active->lrheader = IsDlgButtonChecked(hwnd, 4221);
  426.                     global.active->nofirstpage = IsDlgButtonChecked(hwnd, 4222);
  427.                     EndDialog(hwnd, FALSE);
  428.                     return (TRUE);
  429.  
  430.                 case IDCANCEL:
  431.                     EndDialog(hwnd, TRUE);
  432.                     return (TRUE);
  433.             }
  434.             break;
  435.     }
  436.  
  437.     return (FALSE);
  438. }
  439.  
  440.  
  441.  
  442. static int SearchForFiles (HWND hwnd, KANJI *buffer, BOOL recurrsive)
  443. {
  444.     int i, k, n, len, fd;
  445.     int num = 0, dirs = 0;
  446.     char *cp;
  447.     BOOL hascriteria = FALSE;
  448.     OFSTRUCT of;
  449.     struct ffblk ffblk;
  450.     FILEHEADER header;
  451.  
  452.  
  453.     for (i = 0; i < NRSUMMARIES; i++) {
  454.         if (criteria[i] != NULL) hascriteria = TRUE;
  455.     }
  456.  
  457.     /* Get sub-directories */
  458.  
  459.     if (recurrsive && findfirst("*.*", &ffblk, FA_RDONLY | FA_DIREC) == 0) {
  460.         do {
  461.             if (ffblk.ff_name[0] == '.') continue;
  462.             if (!(ffblk.ff_attrib & FA_DIREC)) continue;
  463.             dirs++;
  464.         } while (findnext(&ffblk) == 0);
  465.  
  466.         if (dirs > 0) {
  467.             i = 0;
  468.             cp = (char *) MemAlloc(dirs * FILENAMELEN);
  469.  
  470.             findfirst("*.*", &ffblk, FA_RDONLY | FA_DIREC);
  471.  
  472.             do {
  473.                 if (ffblk.ff_name[0] == '.') continue;
  474.                 if (!(ffblk.ff_attrib & FA_DIREC)) continue;
  475.                 strcpy(cp + i * FILENAMELEN, ffblk.ff_name);
  476.                 i++;
  477.             } while (findnext(&ffblk) == 0);
  478.         }
  479.     }
  480.  
  481.  
  482.     /* Get files */
  483.  
  484.     if (findfirst(filespec == NULL ? "*.*" : filespec, &ffblk, FA_RDONLY) == 0) {
  485.         do {
  486.             if (ffblk.ff_name[0] == '.') continue;
  487.             if (ffblk.ff_attrib & FA_DIREC) continue;
  488.  
  489.             fd = OpenFile(ffblk.ff_name, &of, OF_READ);
  490.             if (fd < 0) continue;
  491.  
  492.             StatusMessage(of.szPathName);
  493.  
  494.             if (hascriteria) {
  495.                 lseek(fd, 0L, 0);
  496.                 read (fd, &header, sizeof(FILEHEADER));
  497.                 if (header.magic == MAGIC && header.summary) {
  498.                     for (i = 0; i < NRSUMMARIES; i++) {
  499.                         read(fd, &n, sizeof(int));
  500.                         if (n > 0) read(fd, (char *) buffer, n * sizeof(KANJI));
  501.                         if (criteria[i] == NULL) continue;
  502.  
  503.                         len = kanjilen(criteria[i]);
  504.                         if (n < len) break;
  505.                         for (k = 0; k < n - len; k++) {
  506.                             if (!kanjincmp(criteria[i], buffer + k, len)) break;
  507.                         }
  508.                         if (k >= n - len) break;
  509.                     }
  510.  
  511.                     if (i >= NRSUMMARIES) {
  512.                         SendMessage(hwnd, LB_ADDSTRING, 0, (LONG) ((char far *) &of.szPathName));
  513.                         num++;
  514.                     }
  515.                     }
  516.             } else {
  517.                 SendMessage(hwnd, LB_ADDSTRING, 0, (LONG) ((char far *) &of.szPathName));
  518.                 num++;
  519.             }
  520.             close(fd);
  521.         } while (findnext(&ffblk) == 0);
  522.     }
  523.  
  524.  
  525.     /* Recurrse into sub-directories */
  526.  
  527.     if (dirs > 0) {
  528.         for (i = 0; i < dirs; i++) {
  529.             if (chdir(cp + i * FILENAMELEN) < 0) continue;
  530.             num += SearchForFiles(hwnd, buffer, TRUE);
  531.             chdir("..");
  532.         }
  533.  
  534.         FreeMem(cp);
  535.     }
  536.  
  537.     return (num);
  538. }
  539.  
  540.  
  541.  
  542. BOOL FAR PASCAL CriteriaProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  543. {
  544.     switch (message) {
  545.         case WM_INITDIALOG: {
  546.             int i;
  547.             FILEOPTIONS *f;
  548.  
  549.             /* Set the type and mode-change icon of the Jedit controls */
  550.  
  551.             SendDlgItemMessage(hwnd, 4211, EM_LIMITTEXT, 120, 0L);
  552.             if (filespec != NULL) SetDlgItemText(hwnd, 4211, filespec);
  553.  
  554.             for (i = 0; i < NRSUMMARIES; i++) {
  555.                 SendDlgItemMessage(hwnd, 4201 + i, EM_SETRECT, GetDlgItem(hwnd, 4221), 0L);
  556.                 f = (FILEOPTIONS *) SendDlgItemMessage(hwnd, 4201 + i, EM_GETHANDLE, 0, 0L);
  557.  
  558.                 if (criteria[i] != NULL) {
  559.                     SendDlgItemMessage(hwnd, 4201 + i, EM_REPLACESEL, 0, (LONG) criteria[i]);
  560.                 }
  561.                 if (i == 0) {
  562.                     SendDlgItemMessage(hwnd, 4221, EM_SETHANDLE, f->hwnd, 0L);  /* icon-change */
  563.                 }
  564.             }
  565.  
  566.             SetFocus(GetDlgItem(hwnd, 4211));
  567.             CenterDialogBox(hwnd);
  568.             return (TRUE);
  569.         }
  570.  
  571.         case WM_PAINT: {
  572.             int i;
  573.             HDC hdc;
  574.             PAINTSTRUCT ps;
  575.  
  576.             hdc = BeginPaint(hwnd, &ps);
  577.  
  578.             for (i = 0; i < NRSUMMARIES; i++) DrawBoundingBox(hwnd, hdc, 4201 + i);
  579.  
  580.             EndPaint(hwnd, &ps);
  581.             return (TRUE);
  582.         }
  583.  
  584.         case WM_COMMAND:
  585.             switch (wParam) {
  586.                 case IDOK: {
  587.                     int i, j, len;
  588.                     UNIT far *up;
  589.                     KANJI far *kp;
  590.                     char far *cbufp;
  591.                     KANJI buffer[MAXLINELEN];
  592.  
  593.  
  594.                     cbufp = (char far *) buffer;
  595.                     GetDlgItemText(hwnd, 4211, cbufp, 120);
  596.  
  597.                     /* Trims spaces */
  598.  
  599.                     for (i = _fstrlen(cbufp) - 1; i >= 0 && cbufp[i] <= ' '; i--);
  600.                     cbufp[i+1] = '\0';
  601.                     for (i = 0; cbufp[i] && cbufp[i] <= ' '; i++);
  602.                     if (!cbufp[i]) {
  603.                         if (filespec != NULL) FreeMem(filespec);
  604.                         filespec = NULL;
  605.                     } else {
  606.                         if (filespec != NULL) FreeMem(filespec);
  607.                         filespec = (char *) MemAlloc(_fstrlen(cbufp + i) + 5);
  608.                         _fstrcpy(filespec, cbufp + i);
  609.                     }
  610.  
  611.                     /* Get the summary criteria */
  612.  
  613.                     for (i = 0; i < NRSUMMARIES; i++) {
  614.                         up = (UNIT far *) SendDlgItemMessage(hwnd, 4201 + i, EM_GETLINE, 0, 0L);
  615.                         len = unitlen(up);
  616.  
  617.                         if (len <= 0) {
  618.                             if (criteria[i] != NULL) {
  619.                                 FreeBlock(criteria[i]);
  620.                                 criteria[i] = NULL;
  621.                             }
  622.                         } else {
  623.                             kp = criteria[i];
  624.                             if (kp == NULL) {
  625.                                 kp = (KANJI far *) BlockAlloc((len + 5) * sizeof(KANJI));
  626.                             } else if ((SegHeapGetSize(kp) / sizeof(KANJI)) < len + 5) {
  627.                                 FreeBlock(kp);
  628.                                 kp = (KANJI far *) BlockAlloc((len + 5) * sizeof(KANJI));
  629.                             }
  630.                             for (j = 0; up[j].kanji; j++) kp[j] = up[j].kanji;
  631.                             kp[j] = 0;
  632.                             criteria[i] = kp;
  633.                         }
  634.                     }
  635.                     EndDialog(hwnd, TRUE);
  636.                     return (TRUE);
  637.                 }
  638.  
  639.                 case IDCANCEL:
  640.                     EndDialog(hwnd, FALSE);
  641.                     return (TRUE);
  642.             }
  643.             break;
  644.     }
  645.  
  646.     return (FALSE);
  647. }
  648.  
  649.  
  650.  
  651. BOOL FAR PASCAL FileInfoProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  652. {
  653.     switch (message) {
  654.         case WM_INITDIALOG: {
  655.             int i, n, fd;
  656.             struct ffblk ffblk;
  657.             struct stat statbuf;
  658.             OFSTRUCT of;
  659.             FILEHEADER header;
  660.             char buffer[MAXLINELEN];
  661.  
  662.             SetDlgItemText(hwnd, 4211, FileInfoName);
  663.             if (findfirst(FileInfoName, &ffblk, FA_RDONLY) != 0) return (TRUE);
  664.  
  665.             /* File date and time */
  666.  
  667.             if (stat(FileInfoName, &statbuf) == 0) {
  668.                 SetDlgItemText(hwnd, 4212, ctime(&statbuf.st_ctime));
  669.                 SetDlgItemText(hwnd, 4213, ctime(&statbuf.st_mtime));
  670.                 sprintf(buffer, "%ld bytes, %4.2lf K", statbuf.st_size, ((double) statbuf.st_size / 1024.0));
  671.                 SetDlgItemText(hwnd, 4214, buffer);
  672.             }
  673.  
  674.             /* File type */
  675.  
  676.             fd = OpenFile(FileInfoName, &of, OF_READ);
  677.             if (fd < 0) return (TRUE);
  678.  
  679.             lseek(fd, 0L, 0);
  680.             read (fd, &header, sizeof(FILEHEADER));
  681.  
  682.             if (header.magic == MAGIC) {
  683.                 strcpy(buffer, PROGNAME " File");
  684.             } else {
  685.                 strcpy(buffer, "DOS file");
  686.             }
  687.  
  688.             if (ffblk.ff_attrib & FA_DIREC) {
  689.                 if (buffer[0]) strcat(buffer, ", ");
  690.                 strcat(buffer, "Directory");
  691.             }
  692.             if (ffblk.ff_attrib & FA_RDONLY) {
  693.                 if (buffer[0]) strcat(buffer, ", ");
  694.                 strcat(buffer, "Read-Only");
  695.             }
  696.             if (ffblk.ff_attrib & FA_ARCH) {
  697.                 if (buffer[0]) strcat(buffer, ", ");
  698.                 strcat(buffer, "Archive bit set");
  699.             }
  700.  
  701.             SetDlgItemText(hwnd, 4215, buffer);
  702.  
  703.             /* Summary? */
  704.  
  705.             if (header.magic == MAGIC && header.summary) {
  706.                 for (i = 0; i < NRSUMMARIES; i++) {
  707.                     read(fd, &n, sizeof(int));
  708.                     if (n <= 0) continue;
  709.                     if (n > 0) read(fd, buffer, n * sizeof(KANJI));
  710.                     SendDlgItemMessage(hwnd, 4201 + i, EM_REPLACESEL, 0, (LONG) buffer);
  711.                 }
  712.             }
  713.  
  714.             close(fd);
  715.             CenterDialogBox(hwnd);
  716.             return (TRUE);
  717.         }
  718.  
  719.         case WM_COMMAND:
  720.             switch (wParam) {
  721.                 case IDOK:
  722.                     EndDialog(hwnd, TRUE);
  723.                     return (TRUE);
  724.             }
  725.             break;
  726.  
  727.         case WM_KEYDOWN:
  728.             switch (wParam) {
  729.                 case VK_ESCAPE: SendMessage(hwnd, WM_COMMAND, IDOK, 0L);
  730.                                 return (TRUE);
  731.             }
  732.             break;
  733.     }
  734.  
  735.     return (FALSE);
  736. }
  737.  
  738.  
  739.  
  740. static int FillDirectories (HWND ListBoxHwnd, HWND TextHwnd)
  741. {
  742.     int i, n = 0;
  743.     struct ffblk ffblk;
  744.     char buffer[MAXPATH];
  745.  
  746.     if (getcwd(buffer, MAXPATH) == NULL) {
  747.         if (chdir("\\") < 0) return (-1);
  748.         strcpy(buffer, "\\");
  749.     }
  750.  
  751.     /* Fill the directory combo box */
  752.  
  753.     SendMessage(ListBoxHwnd, WM_SETREDRAW, FALSE, 0L);
  754.     SendMessage(ListBoxHwnd, LB_RESETCONTENT, 0, 0L);
  755.  
  756.     if (strcmp(buffer + 2, "\\")) {
  757.         SendMessage(ListBoxHwnd, LB_ADDSTRING, 0, (LONG) ((char far *) PARENTDIR));
  758.         n++;
  759.         strcat(buffer, "\\*.*");
  760.     } else {
  761.         strcat(buffer, "*.*");
  762.     }
  763.  
  764.     if (findfirst(buffer, &ffblk, FA_RDONLY | FA_DIREC) == 0) {
  765.         do {
  766.             if (!(ffblk.ff_attrib & FA_DIREC)) continue;
  767.             if (ffblk.ff_name[0] == '.') continue;
  768.  
  769.             n++;
  770.             SendMessage(ListBoxHwnd, LB_ADDSTRING, 0, (LONG) ((char far *) ffblk.ff_name));
  771.         } while (findnext(&ffblk) == 0);
  772.     }
  773.  
  774.     /* Fill the drives */
  775.  
  776.     for (i = 0; i < 26; i++) {
  777.         if (i == getdisk()) continue;
  778.         switch (GetDriveType(i)) {
  779.             case DRIVE_REMOVABLE:
  780.                 sprintf(buffer, "%c %c: floppy drive ]", DRIVECHAR, 'A' + i);
  781.                 break;
  782.  
  783.             case DRIVE_REMOTE:
  784.                 sprintf(buffer, "%c %c: network drive ]", DRIVECHAR, 'A' + i);
  785.                 break;
  786.  
  787.             case DRIVE_FIXED:
  788.                 sprintf(buffer, "%c %c: hard drive ]", DRIVECHAR, 'A' + i);
  789.                 break;
  790.  
  791.             default: continue;
  792.         }
  793.         SendMessage(ListBoxHwnd, LB_ADDSTRING, 0, (LONG) ((char far *) buffer));
  794.     }
  795.  
  796.     if (SendMessage(ListBoxHwnd, LB_GETCOUNT, 0, 0L) > 0) {
  797.         SendMessage(ListBoxHwnd, LB_SETCURSEL, 0, 0L);
  798.     }
  799.  
  800.     getcwd(buffer, MAXPATH);
  801.     SetWindowText(TextHwnd, buffer);
  802.  
  803.     SendMessage(ListBoxHwnd, WM_SETREDRAW, TRUE, 0L);
  804.     InvalidateRect(ListBoxHwnd, NULL, TRUE);
  805.  
  806.     return (n);
  807. }
  808.  
  809.  
  810. BOOL FAR PASCAL FileFindProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  811. {
  812.     switch (message) {
  813.         case WM_INITDIALOG:
  814.             FillDirectories(GetDlgItem(hwnd, 4221), GetDlgItem(hwnd, 4222));
  815.  
  816.             /* Default to search only the current path */
  817.  
  818.             SendDlgItemMessage(hwnd, 4231, BM_SETCHECK, TRUE, 0L);
  819.             EnableWindow(GetDlgItem(hwnd, 4201), FALSE);
  820.             EnableWindow(GetDlgItem(hwnd, 4202), FALSE);
  821.  
  822.             CenterDialogBox(hwnd);
  823.             return (TRUE);
  824.  
  825.         case WM_COMMAND:
  826.             switch (wParam) {
  827.                 case 4211:      /* Files list */
  828.                     switch (HIWORD(lParam)) {
  829.                         case LBN_DBLCLK:
  830.                             SendMessage(hwnd, WM_COMMAND, 4201, 0L);    /* Open */
  831.                             return (TRUE);
  832.                     }
  833.                     return (TRUE);
  834.  
  835.                 case 4221: {    /* Directories */
  836.                     int i;
  837.                     char buffer[MAXPATH];
  838.  
  839.                     switch (HIWORD(lParam)) {
  840.                         case LBN_DBLCLK:
  841.                             i = SendDlgItemMessage(hwnd, 4221, LB_GETCURSEL, 0, 0L);
  842.                             if (i == LB_ERR) {
  843.                                 MessageBeep(0);
  844.                                 return (TRUE);
  845.                             }
  846.                             SendDlgItemMessage(hwnd, 4221, LB_GETTEXT, i, (LONG) ((char far *) buffer));
  847.                             if (!strcmp(buffer, PARENTDIR)) {
  848.                                 chdir("..");
  849.                             } else if (buffer[0] == DRIVECHAR) {
  850.                                 setdisk(buffer[2] - 'A');
  851.                             } else {
  852.                                 chdir(buffer);
  853.                             }
  854.                             FillDirectories(GetDlgItem(hwnd, 4221), GetDlgItem(hwnd, 4222));
  855.                             return (TRUE);
  856.                     }
  857.                     return (TRUE);
  858.                 }
  859.  
  860.                 case 4231:      /* Current path */
  861.                     if (IsDlgButtonChecked(hwnd, 4231)) {
  862.                         EnableWindow(GetDlgItem(hwnd, 4221), TRUE);
  863.                         EnableWindow(GetDlgItem(hwnd, 4222), TRUE);
  864.                     }
  865.                     return (TRUE);
  866.  
  867.                 case 4232:      /* All subdirectories */
  868.                     if (IsDlgButtonChecked(hwnd, 4232)) {
  869.                         EnableWindow(GetDlgItem(hwnd, 4221), TRUE);
  870.                         EnableWindow(GetDlgItem(hwnd, 4222), TRUE);
  871.                     }
  872.                     return (TRUE);
  873.  
  874.                 case 4233:      /* Entire disk */
  875.                     if (IsDlgButtonChecked(hwnd, 4233)) {
  876.                         EnableWindow(GetDlgItem(hwnd, 4221), FALSE);
  877.                         EnableWindow(GetDlgItem(hwnd, 4222), FALSE);
  878.                     }
  879.                     return (TRUE);
  880.  
  881.                 case 4234:      /* All drives */
  882.                     if (IsDlgButtonChecked(hwnd, 4234)) {
  883.                         EnableWindow(GetDlgItem(hwnd, 4221), FALSE);
  884.                         EnableWindow(GetDlgItem(hwnd, 4222), FALSE);
  885.                     }
  886.                     return (TRUE);
  887.  
  888.                 case 4201: {    /* Open */
  889.                     int i;
  890.                     char buffer[MAXPATH];
  891.  
  892.                     i = SendDlgItemMessage(hwnd, 4211, LB_GETCURSEL, 0, 0L);
  893.                     if (i == LB_ERR) return (TRUE);
  894.                     SendDlgItemMessage(hwnd, 4211, LB_GETTEXT, i, (LONG) ((char far *) buffer));
  895.                     if (!DoFileOpen(buffer)) return (TRUE);
  896.  
  897.                     EndDialog(hwnd, TRUE);
  898.                     return (TRUE);
  899.                 }
  900.  
  901.                 case 4202: {    /* Info */
  902.                     int i;
  903.                     char buffer[MAXPATH];
  904.  
  905.                     i = SendDlgItemMessage(hwnd, 4211, LB_GETCURSEL, 0, 0L);
  906.                     if (i == LB_ERR) return (TRUE);
  907.                     SendDlgItemMessage(hwnd, 4211, LB_GETTEXT, i, (LONG) ((char far *) buffer));
  908.                     FileInfoName = buffer;
  909.  
  910.                     DialogBox(hInstance, "FileInfo", hwnd, FileInfoProc);
  911.                     return (TRUE);
  912.                 }
  913.  
  914.                 case IDOK: {    /* Search */
  915.                     BOOL Doit;
  916.                     HCURSOR hcursor;
  917.  
  918.                     Doit = DialogBox(hInstance, "SearchCriteria", hwnd, CriteriaProc);
  919.  
  920.                     if (Doit) {
  921.                         int i, n, OldDrive = -1;
  922.                         BOOL Recurrsive = FALSE;
  923.                         char OldPath[MAXPATH] = "";
  924.                         KANJI buffer[MAXLINELEN];
  925.  
  926.                         if (IsDlgButtonChecked(hwnd, 4232)) {   /* Sub-directories */
  927.                             Recurrsive = TRUE;
  928.                         }
  929.                         if (IsDlgButtonChecked(hwnd, 4233)) {   /* Entire disk */
  930.                             getcwd(OldPath, MAXPATH);
  931.                             chdir("\\");
  932.                             Recurrsive = TRUE;
  933.                         }
  934.                         if (IsDlgButtonChecked(hwnd, 4234)) {   /* All disks */
  935.                             OldDrive = getdisk();
  936.                             Recurrsive = TRUE;
  937.                         }
  938.  
  939.                         hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  940.                         ShowCursor(TRUE);
  941.                         SendDlgItemMessage(hwnd, 4211, LB_RESETCONTENT, 0, 0L);
  942.  
  943.                         if (IsDlgButtonChecked(hwnd, 4234)) {
  944.                             for (n = i = 0; i < 26; i++) {
  945.                                 switch (GetDriveType(i)) {
  946.                                     default:
  947.                                     case DRIVE_REMOVABLE: break;
  948.  
  949.                                     case DRIVE_REMOTE:
  950.                                     case DRIVE_FIXED:
  951.                                         setdisk(i);
  952.                                         if (getdisk() != i) break;
  953.  
  954.                                         getcwd(OldPath, MAXPATH);
  955.                                         chdir("\\");
  956.                                         n += SearchForFiles (GetDlgItem(hwnd, 4211), buffer, TRUE);
  957.                                         chdir(OldPath);
  958.                                         break;
  959.                                 }
  960.                             }
  961.                             OldPath[0] = '\0';
  962.                         } else {
  963.                             n = SearchForFiles (GetDlgItem(hwnd, 4211), buffer, Recurrsive);
  964.                         }
  965.  
  966.                         if (n <= 0) {
  967.                             ShowCursor(FALSE);
  968.                             SetCursor(hcursor);
  969.                             StatusMessage("");
  970.                             ErrorMessage (hwnd, "No files found!");
  971.                             EnableWindow(GetDlgItem(hwnd, 4201), FALSE);
  972.                             EnableWindow(GetDlgItem(hwnd, 4202), FALSE);
  973.                         } else {
  974.                             ShowCursor(FALSE);
  975.                             SetCursor(hcursor);
  976.                             sprintf((char *) buffer, "%d file%s found.", n, (n > 1) ? "s" : "");
  977.                             StatusMessage((char *) buffer);
  978.                             SendDlgItemMessage(hwnd, 4211, LB_SETCURSEL, 0, 0L);
  979.                             EnableWindow(GetDlgItem(hwnd, 4201), TRUE);
  980.                             EnableWindow(GetDlgItem(hwnd, 4202), TRUE);
  981.                             SetFocus(GetDlgItem(hwnd, 4211));
  982.                         }
  983.  
  984.                         if (OldDrive >= 0) setdisk(OldDrive);
  985.  
  986.                         if (OldPath[0] != '\0') {
  987.                             chdir(OldPath);
  988.                             FillDirectories(GetDlgItem(hwnd, 4221), GetDlgItem(hwnd, 4222));
  989.                         }
  990.                     }
  991.  
  992.                     return (TRUE);
  993.                 }
  994.  
  995.                 case IDCANCEL:  /* Cancel */
  996.                     EndDialog(hwnd, FALSE);
  997.                     return (TRUE);
  998.             }
  999.             break;
  1000.     }
  1001.  
  1002.     return (FALSE);
  1003. }
  1004.  
  1005.  
  1006.  
  1007. void UpdateQuickFiles (void)
  1008. {
  1009.     int i, j, n;
  1010.     char buffer[MAXLINELEN];
  1011.  
  1012.     for (i = j = 0; i < NRQUICKFILE; i++) {
  1013.         if (QuickFiles[i] != NULL) j++;
  1014.         DeleteMenu(hmenu, IDM_FILE1 + i, MF_BYCOMMAND);
  1015.     }
  1016.  
  1017.     /* Find the last file menu item */
  1018.  
  1019.     for (n = GetMenuItemCount(hmenu) - 1; n >= 0; n--) {
  1020.         if (GetMenuItemID(GetSubMenu(hmenu, n), 0) == IDM_FILENEW) break;
  1021.     }
  1022.  
  1023.     if (n < 0) return;
  1024.  
  1025.     for (i = GetMenuItemCount(GetSubMenu(hmenu, n)) - 1; i >= 0; i--) {
  1026.         if (GetMenuItemID(GetSubMenu(hmenu, n), i) == IDM_FILEEXIT) break;
  1027.     }
  1028.  
  1029.     if (i >= 0) DeleteMenu(GetSubMenu(hmenu, n), i+1, MF_BYPOSITION);
  1030.  
  1031.     if (j > 0) {
  1032.         InsertMenu(GetSubMenu(hmenu, n), i+1, MF_BYPOSITION | MF_SEPARATOR, 0, "");
  1033.  
  1034.         for (i = 0; i < NRQUICKFILE && QuickFiles[i] != NULL; i++) {
  1035.             sprintf(buffer, "&%d %s", i + 1, QuickFiles[i]);
  1036.             InsertMenu(GetSubMenu(hmenu, n), -1, MF_BYPOSITION | MF_UNCHECKED | MF_ENABLED | MF_STRING, IDM_FILE1 + i, buffer);
  1037.         }
  1038.     }
  1039. }
  1040.  
  1041.  
  1042.  
  1043. void PutQuickFile (char *pathname)
  1044. {
  1045.     int i, j;
  1046.  
  1047.     for (i = 0; i < NRQUICKFILE; i++) {
  1048.         if (!stricmp(QuickFiles[i], pathname)) {
  1049.             FreeMem(QuickFiles[i]);
  1050.             for (j = i+1; j < NRQUICKFILE; j++) QuickFiles[j-1] = QuickFiles[j];
  1051.             QuickFiles[NRQUICKFILE-1] = NULL;
  1052.         }
  1053.     }
  1054.  
  1055.     if (QuickFiles[NRQUICKFILE-1] != NULL) FreeMem(QuickFiles[NRQUICKFILE-1]);
  1056.  
  1057.     for (i = NRQUICKFILE - 1; i > 0; i--) QuickFiles[i] = QuickFiles[i-1];
  1058.  
  1059.     QuickFiles[0] = MemAlloc(strlen(pathname) + 5);
  1060.     strcpy(QuickFiles[0], pathname);
  1061.  
  1062.     UpdateQuickFiles();
  1063.     OptionsChanged = TRUE;
  1064. }
  1065.  
  1066.  
  1067. char *GetQuickFile (int n)
  1068. {
  1069.     return (QuickFiles[n]);
  1070. }
  1071.  
  1072.  
  1073.  
  1074. BOOL FAR PASCAL RunProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  1075. {
  1076.     switch (message) {
  1077.         case WM_INITDIALOG: {
  1078.             int i;
  1079.  
  1080.             for (i = 0; i < NRPROGS; i++) {
  1081.                 SendDlgItemMessage(hwnd, 4201 + i, BM_SETCHECK, (i == 0), 0L);
  1082.             }
  1083.  
  1084.             CenterDialogBox(hwnd);
  1085.             return (TRUE);
  1086.         }
  1087.  
  1088.         case WM_COMMAND:
  1089.             switch (wParam) {
  1090.                 case IDOK: {
  1091.                     int len;
  1092.                     char *cp;
  1093.                     char pathname[MAXLINELEN];
  1094.  
  1095.                     GetWindowsDirectory(pathname, MAXLINELEN);
  1096.                     len = strlen(pathname);
  1097.                     if (pathname[len-1] == '\\') pathname[len-1] = '\0';
  1098.  
  1099.                     if (IsDlgButtonChecked(hwnd, 4201)) {
  1100.                         strcat(pathname, "\\CONTROL.EXE");
  1101.                         cp = "Control Panel";
  1102.                     } else if (IsDlgButtonChecked(hwnd, 4202)) {
  1103.                         strcat(pathname, "\\WINFILE.EXE");
  1104.                         cp = "File Manager";
  1105.                     } else if (IsDlgButtonChecked(hwnd, 4203)) {
  1106.                         sprintf(pathname, "%sBTNMAD.EXE", global.jwppath);
  1107.                         cp = "Button Madness";
  1108.                     } else if (IsDlgButtonChecked(hwnd, 4204)) {
  1109.                         sprintf(pathname, "%sPUZZLE.EXE", global.jwppath);
  1110.                         cp = "Puzzle";
  1111.                     } else {
  1112.                         pathname[0] = '\0';
  1113.                         cp = NULL;
  1114.                     }
  1115.  
  1116.                     if (cp != NULL) {
  1117.                         if (WinExec(pathname, SW_SHOW) < 32)
  1118.                             ErrorMessage(hwnd, "Cannot run %s!", cp);
  1119.                     }
  1120.                     EndDialog(hwnd, TRUE);
  1121.                     return (TRUE);
  1122.                 }
  1123.  
  1124.                 case IDCANCEL:
  1125.                     EndDialog(hwnd, FALSE);
  1126.                     return (TRUE);
  1127.  
  1128.                 case 4201:
  1129.                 case 4202:
  1130.                 case 4203:
  1131.                 case 4204: {
  1132.                     int i;
  1133.  
  1134.                     for (i = 0; i < NRPROGS; i++)
  1135.                         SendDlgItemMessage(hwnd, 4201 + i, BM_SETCHECK, (4201 + i == wParam), 0L);
  1136.  
  1137.                     if (HIWORD(lParam) == BN_DOUBLECLICKED) SendMessage(hwnd, WM_COMMAND, IDOK, 0L);
  1138.                     return (TRUE);
  1139.                 }
  1140.             }
  1141.             break;
  1142.     }
  1143.  
  1144.     return (FALSE);
  1145. }
  1146.  
  1147.  
  1148.  
  1149. static KANJI far *ConvertOffset (int id, LONG lParam, KANJI *buf)
  1150. {
  1151.     if (Templates == NULL) {
  1152.         buf[0] = 0;
  1153.         return (buf);
  1154.     }
  1155.     return (Templates[lParam].desc);
  1156. }
  1157.  
  1158.  
  1159.  
  1160. BOOL FAR PASCAL TemplateProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  1161. {
  1162.     switch (message) {
  1163.         case WM_INITDIALOG: {
  1164.             int i, j, fd;
  1165.             OFSTRUCT of;
  1166.             FILEHEADER header;
  1167.             struct ffblk ffblk;
  1168.             KANJI tplname[MAXLINELEN];
  1169.             char buffer[MAXLINELEN];
  1170.  
  1171.  
  1172.             sprintf(buffer, "%s*%s", global.jwppath, FileExtensions[FF_TEMPLATE]);
  1173.             StatusMessage("Loading templates...");
  1174.  
  1175.             j = 0;
  1176.  
  1177.             if (findfirst(buffer, &ffblk, FA_RDONLY) == 0) {
  1178.                 do {
  1179.                     fd = OpenFile(ffblk.ff_name, &of, OF_READ);
  1180.                     if (fd < 0) continue;
  1181.  
  1182.                     lseek(fd, 0L, 0);
  1183.                     read (fd, &header, sizeof(FILEHEADER));
  1184.                     if (header.magic != MAGIC) {
  1185.                         close(fd);
  1186.                         continue;
  1187.                     }
  1188.  
  1189.                     if (!header.summary) {
  1190.                         for (i = 0; ffblk.ff_name[i]; i++) tplname[i] = ffblk.ff_name[i];
  1191.                         tplname[i] = 0;
  1192.                     } else {
  1193.                         read(fd, &i, sizeof(int));
  1194.                         if (i > 0) read(fd, (char *) tplname, i * sizeof(KANJI));
  1195.                         else {
  1196.                             for (i = 0; ffblk.ff_name[i]; i++) tplname[i] = ffblk.ff_name[i];
  1197.                             tplname[i] = 0;
  1198.                         }
  1199.                     }
  1200.  
  1201.                     close(fd);
  1202.  
  1203.                     if (Templates == NULL) {
  1204.                         Templates = (TPLFILE far *) BlockAlloc(TPLBLOCKSIZE * sizeof(TPLFILE));
  1205.                     } else if (j % TPLBLOCKSIZE == 0) {
  1206.                         Templates = (TPLFILE far *) BlockRealloc(Templates, (j + TPLBLOCKSIZE) * sizeof(TPLFILE));
  1207.                     }
  1208.                     Templates[j].filename = (char far *) BlockAlloc(strlen(of.szPathName) + 5);
  1209.                     _fstrcpy(Templates[j].filename, of.szPathName);
  1210.                     Templates[j].desc = (KANJI far *) BlockAlloc((kanjilen(tplname) + 5) * sizeof(KANJI));
  1211.                     kanjicpy(Templates[j].desc, tplname);
  1212.  
  1213.                     SendDlgItemMessage(hwnd, 4201, LB_ADDSTRING, 0, (LONG) j);
  1214.                     j++;
  1215.                 } while (findnext(&ffblk) == 0);
  1216.             }
  1217.  
  1218.             StatusMessage("");
  1219.  
  1220.             if (j <= 0) {
  1221.                 EndDialog(hwnd, -1);
  1222.                 return (TRUE);
  1223.             }
  1224.  
  1225.             SendDlgItemMessage(hwnd, 4201, LB_SETCURSEL, 0, 0L);
  1226.  
  1227.             nr_templates = j;
  1228.  
  1229.             return (TRUE);
  1230.         }
  1231.  
  1232.         case WM_COMMAND: {
  1233.             int i, j = -5;
  1234.  
  1235.             switch (wParam) {
  1236.                 case 4201:          /* Japanese list box */
  1237.                     if (HIWORD(lParam) == LBN_DBLCLK) {
  1238.                         SendMessage(hwnd, WM_COMMAND, IDOK, 0L);
  1239.                     }
  1240.                     return (TRUE);
  1241.  
  1242.                 case IDOK:
  1243.                     j = SendDlgItemMessage(hwnd, 4201, LB_GETCURSEL, 0, 0L);
  1244.                     if (j == LB_ERR) {
  1245.                         j = -1;
  1246.                         if (TplChosen != NULL) TplChosen[0] = '\0';
  1247.                     } else {
  1248.                         j = SendDlgItemMessage(hwnd, 4201, LB_GETITEMDATA, j, 0L);
  1249.                         if (TplChosen == NULL) TplChosen = BlockAlloc(MAXPATH);
  1250.                         _fstrcpy(TplChosen, Templates[j].filename);
  1251.                     }
  1252.                     break;
  1253.  
  1254.                 case IDCANCEL:
  1255.                     j = -2;
  1256.                     if (TplChosen != NULL) TplChosen[0] = '\0';
  1257.                     break;
  1258.  
  1259.                 case 4211:
  1260.                     j = -1;
  1261.                     if (TplChosen != NULL) TplChosen[0] = '\0';
  1262.                     break;
  1263.             }
  1264.  
  1265.             if (j <= -5) return (FALSE);
  1266.  
  1267.             for (i = 0; i < nr_templates; i++) {
  1268.                 FreeBlock(Templates[i].filename);
  1269.                 FreeBlock(Templates[i].desc);
  1270.             }
  1271.             FreeBlock(Templates);
  1272.             Templates = NULL;
  1273.             EndDialog(hwnd, j);
  1274.             return (TRUE);
  1275.         }
  1276.  
  1277.         case WM_COMPAREITEM:
  1278.         case WM_DELETEITEM:
  1279.         case WM_DRAWITEM:
  1280.         case WM_MEASUREITEM:
  1281.             return (JlistProc(hwnd, message, wParam, lParam, TRUE, ConvertOffset));
  1282.     }
  1283.  
  1284.     return (FALSE);
  1285. }
  1286.